@node Calling C functions from Scheme
@section Calling C functions from Scheme

@cindex importing C functions to Scheme
@stindex external-calls
The @code{external-calls} structure exports several ways to call C
functions from Scheme, along with several other related utilities,
many of which are also available from other structures.  There are two
different ways to call C functions from Scheme, depending on how the C
function was obtained:

@deffn {Scheme procedure} call-imported-binding binding argument @dots{} @returns{} value
@deffnx {Scheme procedure} call-external-value byte-vector name argument @dots{} @returns{} value
Each of these applies its first argument, a C function, to the rest of
the arguments.  For @code{call-imported-binding}, the function argument
must be an imported binding.  For @code{call-external-value}, the
function argument must be a byte vector that contains a pointer to a C
function, and @var{name} should be a string that names the function.
The @var{name} argument is used only for printing error messages.

For both of these, the C function is passed the argument values, and
the value returned is that returned by the C function.  No automatic
representation conversion occurs for either arguments or return
values.  Up to twelve arguments may be passed.  There is no method
supplied for returning multiple values to Scheme from C or vice versa
(mainly because C does not have multiple return values).

Keyboard interrupts that occur during a call to a C function are
ignored until the function returns to Scheme.@footnote{This is clearly
a problem; we are working on a solution.}
@end deffn

@cindex importing C functions to Scheme
@deffn {Scheme syntax} import-definition name [c-string]
@deffnx {Scheme syntax} import-lambda-definition name formals [c-string]
These macros simplify importing bindings from C into Scheme and
wrapping such bindings in Scheme procedures.  @code{Import-definition}
defines @var{name} to be the shared binding named by @var{c-string},
whose value, if it is not supplied, is by default a string of
@var{name}, downcased and with all hyphens translated to underscores.

@lisp
(define @var{name} (lookup-imported-binding @var{c-string}))@end lisp

@noindent
For example,

@lisp
(import-definition my-foo)
    @expansion{} (define my-foo (lookup-imported-binding "my_foo"))@end lisp

@code{Import-lambda-definition} imports the named C binding, using
either the provided C binding name or by translating the Scheme name
as with @code{import-definition}, and defines @var{name} to be a
procedure with the given formal parameter list that calls the imported
C binding with its arguments:

@lisp
(define @var{binding} (lookup-imported-binding @var{c-string}))
(define (@var{name} @var{formal} @dots{})
  (call-imported-binding @var{binding} @var{formal} @dots{}))@end lisp

@noindent
Examples:

@lisp
(import-lambda-definition integer->process-id (int)
                          "posix_getpid")
    @expansion{}
(define @var{binding@sub{0}}
        (lookup-imported-binding "posix_getpid"))
(define (integer->process-id int)
  (call-imported-binding @var{binding@sub{0}} int))

(import-lambda-definition s48-system (string))
    @expansion{}
(define @var{binding@sub{1}}
        (lookup-imported-binding "s48_system"))
(define (s48-system string)
  (call-imported-binding @var{binding@sub{1}} string))@end lisp

@noindent
where @var{binding@sub{0}} and @var{binding@sub{1}} are fresh, unused
variable names.

@strong{Warning:} @code{Import-lambda-definition}, as presently
implemented, requires a fixed parameter list; it does not allow `rest
list' arguments.
@end deffn

@deffn {Scheme procedure} lookup-imported-binding name @returns{} shared-binding
@deffnx {Scheme procedure} define-exported-binding shared-binding @returns{} unspecified
@deffnx {Scheme procedure} shared-binding-ref shared-binding @returns{} value
These are identical to the procedures accessible with the same names
from the @embedref{Shared bindings between Scheme and C,
@code{shared-bindings} structure}.
@end deffn

@deffn {Scheme procedure} add-finalizer! object procedure @returns{} unspecified
Registers @var{procedure} as the finalizer for @var{object}.  When
@var{object} is later about to be reclaimed by the garbage collector,
@var{procedure} is applied to one argument, @var{object}.  All
finalizers are applied in a child of the root scheduler thread that is
spawned after every garbage collection.  If an error occurs in any
finalizer, it will be printed to the standard error output port, and
all other finalizers will be aborted before they are given a chance to
run.  Because of this, and the fact that finalizers are collected and
run after every garbage collection, they should perform as little
computation as possible.  @var{Procedure} may also create new
references to @var{object} elsewhere in the heap, in which case the
object will not be reclaimed, but its associated finalizer will be
forgotten.

@strong{Warning:} Finalizers are expensive.  Use sparingly.
@end deffn

@deffn {Scheme procedure} define-record-resumer record-type resumer @returns{} unspecified
Identical to the procedure accessible with the same name from the
@embedref{Records, @code{record-types} structure}.  Record resumers
are often useful in working with foreign C data, which is in many
cases specific to the program image within the operating system, and
which cannot straightforwardly be relocated to a different address
space.
@end deffn
